/*
 * DialogAboutGLLogo
 * Version: 0.1
 * Date: 2008-10-25
 * Author: gp08-nhn
 */

package keyboardhero;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

// need jogl for it -> only future possibility
// https://jogl.dev.java.net/servlets/ProjectDocumentList?folderID=9260&expandFolder=9260&folderID=0

/**
 * A class to display the logo in 3D in the about box.
 * 
 * @author gp08-nhn
 */
final class DialogAboutGLLogo extends JDialog {
	
	//-------------------- VARIABLES --------------------
	
	/**
	 * A JDialog is a serializable object, thus it requires a unique Serial Version ID.
	 * 
	 * @see java.io.Serializable
	 */
	private static final long serialVersionUID = -617640126576958582L;
	
	private static DialogAboutGLLogo instance = null;
	private Rectangle bounds;
	private DialogAboutGLLogoCanvas logoCanvas;
	
	/**
	 * This is the container adapter added to every container inside the dialog. This method will
	 * add the {@link #keyAdapter} recursively to every component inside the container. It is used
	 * to close the dialog at the press of an escape, enter or space key.
	 */
	private final ContainerAdapter containerAdapter = new ContainerAdapter() {
		public void componentAdded(ContainerEvent e) {
			addListeners(e.getChild());
		} // end method
		/* // unused
		public void componentRemoved(ContainerEvent e) {
		} // end method
		*/
	}; // end class
	
	private final MouseAdapter mouseAdapter = new MouseAdapter() {
		public void mouseClicked(MouseEvent e) {
			setVisible(false);
		}
	}; // end class
	
	private final KeyAdapter keyAdapter = new KeyAdapter() {
		public void keyPressed(KeyEvent e) {
			setVisible(false);
		} // end method
	}; // end class
	
	//-------------------- CORE FUNCTIONS --------------------
	
	private DialogAboutGLLogo() {
		super();
		getRootPane().setWindowDecorationStyle(JRootPane.NONE);
		setUndecorated(true);
		setBackground(Color.BLACK);
		getContentPane().setBackground(Color.BLACK);
		addListeners(this);
		setResizable(false);
		addWindowListener(new WindowAdapter() {
			public void windowDeactivated(final WindowEvent e) {
				setVisible(false);
			} // end method
			
			public void windowLostFocus(final WindowEvent e) {
				setVisible(false);
			} // end method
		} // end class
		);
	}
	
	public void setVisible(boolean b) {
		if(bounds == null) return;
		setBounds(bounds);
		
		final Container contentPane = getContentPane();
		if(b) {
			try {
				contentPane.add(logoCanvas = new DialogAboutGLLogoCanvas(bounds.width, bounds.height));
			} catch(Throwable e) {
				if(Util.getDebugLevel() > 70) e.printStackTrace();
				contentPane.add(new JLabel(new ImageIcon(Util.TOOLKIT.getImage(Util.getURL("Logo.png")))));
			}
		} else {
			bounds = null;
			if(logoCanvas != null) {
				logoCanvas.close();
				logoCanvas = null;
			}
			contentPane.removeAll();
			dispose();
		}
		
		super.setVisible(b);
	}
	
	static final void open(Rectangle bounds) {
		if(instance == null) {
			instance = new DialogAboutGLLogo();
		}
		instance.bounds = bounds;
		instance.setVisible(true);
		
	}
	
	private void addListeners(Component c) {
		c.addKeyListener(keyAdapter);
		c.addMouseListener(mouseAdapter);
		
		if(c instanceof Container) {
			Container container = (Container)c;
			container.addContainerListener(containerAdapter);
			for(Component child : container.getComponents()) {
				addListeners(child);
			} // end for
		} // end if
	} // end method
	
	//-------------------- DEBUGGING FUNCTIONS --------------------
	
	/**
	 * Creates a string containing the most important information about the game. This method is
	 * used only for debugging and testing purposes.
	 * 
	 * @return the created string.
	 */
	static String getString() { //$SUP-MCP$
		return "DialogAboutGLLogo()";
	} // end method
	
	/**
	 * This method serves security purposes. Provides an integrity string that will be checked by
	 * the {@link Connection#integrityCheck()} method; thus the application can only be altered if
	 * the source is known. Every class in the {@link keyboardhero} package has an integrity string.
	 * 
	 * @return the string of this class used for integrity checking.
	 */
	static String getIntegrityString() {
		return "uFgj!+.s_D3-asdf]as";
	} // end method
	
	/**
	 * The tester object of this class. It provides a debugging menu and unit tests for this class.
	 * Its only purpose is debugging or testing.
	 */
	static final Tester tester = new Tester("DialogAboutGLLogo", new String[] {"getString()"} /* end initialization */) { //$SUP-PPA$
		void menu(int choice) throws Exception {
			switch(choice) {
				case 5:
					System.out.println(getString());
					break;
				default:
					baseMenu(choice);
					break;
			} // end switch
		} // end method
		
		void runUnitTests() throws Exception {
			higherTestStart(name);
			
			testEq("getIntegrityString()", "uFgj!+.s_D3-asdf]as", DialogAboutGLLogo.getIntegrityString());
			
			higherTestEnd();
		} // end method
	}; // end class
	
	/**
	 * Starts the class's developing menu. If this build is a developer's one it starts the
	 * application in a normal way with the exception that it starts the debugging tool for this
	 * class as well; otherwise exits with an error message.
	 * 
	 * @param args
	 *            the arguments given to the program.
	 * @see KeyboardHero#startApp()
	 */
	public static void main(String[] args) {
		Tester.mainer(args, tester);
	} // end method
}
